<?php
// +----------------------------------------------------------------------
// | 字符串工具库
// +----------------------------------------------------------------------

namespace helper\util;

trait Str
{
    /**
     * 版本检测
     *
     * @param $current
     * @param $new
     * @return int
     */
    public static function check($current, $new)
    {
        if ($current == $new) return 0;

        $current = explode(".", $current);
        $new = explode(".", $new);
        foreach ($current as $k => $cur) {
            if (isset($new[$k])) {
                if ($cur < $new[$k]) {
                    return -1;
                } elseif ($cur > $new[$k]) {
                    return 1;
                }
            } else {
                return 1;
            }
        }
        return count($new) > count($current) ? -1 : 0;
    }

    /**
     * 生成唯一标志
     * 标准的UUID格式为：xxxxxxxx-xxxx-xxxx-xxxxxx-xxxxxxxxxx(8-4-4-4-12)
     */
    public static function uuid4($is_upper = false)
    {
        $chars = md5(uniqid(mt_rand(), true));
        $str = substr($chars, 0, 8) . '-'
            . substr($chars, 8, 4) . '-'
            . substr($chars, 12, 4) . '-'
            . substr($chars, 16, 4) . '-'
            . substr($chars, 20, 12);
        return $is_upper ? strtoupper($str) : $str;
    }

    /**
     * 数字1转换成001后自增
     * @param int $num
     * @param int $step
     * @return string
     **/
    public static function autoInc($num, $step = 1)
    {
        $count = count(str_split($num));//字符串位数  把字符串分割到数组中
        $num_new = intval($num) + $step;//默认数字增加
        if ($num_new > pow(10, $count - 1)) { //返回 x 的 y 次方
            return $num_new;
        } else {
            return str_pad($num_new, $count, '0', STR_PAD_LEFT);//把字符串填充为新的长度
        }
    }

    /**
     * 隐藏手机号码中间的数字
     * @param string $mobile
     * @return string
     */
    public static function hideMobile($mobile)
    {
        //1.字符串截取法
        //$mobile = substr($mobile,0,3)."****".substr($mobile,7,4);
        //2.替换字符串的子串
        $mobile = substr_replace($mobile, '****', 3, 4);
        //3.用正则
        //$mobile = preg_replace('/(\d{3})\d{4}(\d{4})/', '$1****$2', $mobile);
        return $mobile;
    }

    /**
     * 将一个字符串部分字符用$re替代隐藏
     * @param string $string 待处理的字符串
     * @param int $start 规定在字符串的何处开始，
     *                            正数 - 在字符串的指定位置开始
     *                            负数 - 在从字符串结尾的指定位置开始
     *                            0 - 在字符串中的第一个字符处开始
     * @param int $length 可选。规定要隐藏的字符串长度。默认是直到字符串的结尾。
     *                            正数 - 从 start 参数所在的位置隐藏
     *                            负数 - 从字符串末端隐藏
     * @param string $re 替代符
     * @return string   处理后的字符串
     */
    function hideStr($string, $start = 0, $length = 0, $re = '*')
    {
        if (empty($string)) return false;
        $strArr = array();
        $mb_strLen = mb_strlen($string);
        while ($mb_strLen) {//循环把字符串变为数组
            $strArr[] = mb_substr($string, 0, 1, 'utf8');
            $string = mb_substr($string, 1, $mb_strLen, 'utf8');
            $mb_strLen = mb_strlen($string);
        }
        $strLen = count($strArr);
        $begin = $start >= 0 ? $start : ($strLen - abs($start));
        $end = $last = $strLen - 1;
        if ($length > 0) {
            $end = $begin + $length - 1;
        } elseif ($length < 0) {
            $end -= abs($length);
        }
        for ($i = $begin; $i <= $end; $i++) {
            $strArr[$i] = $re;
        }
        if ($begin >= $end || $begin >= $last || $end > $last) return false;
        return implode('', $strArr);
    }

    /**
     * 唯一订单号
     * @return string
     */
    public static function getOrderSN(): string
    {
        return date('YmdHis') . str_pad(mt_rand(0, 9999), 4, '0', STR_PAD_LEFT);
    }

    /**
     * 获取json数组第一列
     * @param string $json
     * @return string
     */
    public static function getJsonArrFirst(string $json): string
    {
        $arr = json_decode($json, true);
        if ($arr) {
            return current($arr);
        }
        return '';
    }

    /**
     * 解析Url Query
     *
     * @param string $url url地址或URL query参数
     * @return array
     */
    public static function parseUrlQuery($url)
    {
        $index = strpos($url, "?");
        $url = $index === false ? $url : substr($url, $index);
        parse_str($url, $result);
        return $result;
    }

    /**
     * 计算距离
     * @param $lat1
     * @param $lng1
     * @param $lat2
     * @param $lng2
     * @return float|int 单位米
     */
    function getDistance($lat1, $lng1, $lat2, $lng2)
    {
        define('PI', 3.1415926535898);
        define('EARTH_RADIUS', 6378.137);
        $radLat1 = $lat1 * (PI / 180);
        $radLat2 = $lat2 * (PI / 180);

        $a = $radLat1 - $radLat2;
        $b = ($lng1 * (PI / 180)) - ($lng2 * (PI / 180));

        $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
        $s = $s * EARTH_RADIUS;
        $s = round($s * 10000) / 10000;
        return $s * 1000;
    }

    /**
     * 大小替换反转
     *
     * @param string $str
     * @param bool $is_rev
     * @return string
     */
    function bigSmallReplace(string $str, bool $is_rev = false): string
    {
        // Cutting words
        $first = preg_split("/[\s]+/", $str);
        $result = [];

        // Start
        foreach ($first as $f_value) {
            $str_len = strlen($f_value) - 1;
            $i = 0;
            $temp = '';
            while ($str_len >= 0) {
                if (ord($f_value[$str_len]) > 64 && ord($f_value[$str_len]) < 91) {
                    $temp .= strtoupper($f_value[$i]);
                } else if (ord($f_value[$str_len]) > 96 && ord($f_value[$str_len]) < 123) {
                    $temp .= strtolower($f_value[$i]);
                }
                $i++;
                $str_len--;
            }
            $result[] = $is_rev ? strrev($temp) : $temp;
        }
        return implode(' ', $result);
    }
}